package controller

import (
	"fmt"
	"math/rand"
	"net/http"
	"strconv"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/hlPay"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/hlPay/services"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	ucommon "gitee.com/wangshh_123/cross-pay-go/src/utils/common"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// HlAdminController 海连管理员控制器
type HlAdminController struct {
	db          *gorm.DB
	hlPayClient *hlPay.HlPayClient
}

// NewHlAdminController 创建海连管理员控制器实例
func NewHlAdminController(db *gorm.DB, hlPayClient *hlPay.HlPayClient) *HlAdminController {
	return &HlAdminController{
		db:          db,
		hlPayClient: hlPayClient,
	}
}

// HlAdminMatrixTransfer 海连管理员执行矩阵转账
func (c *HlAdminController) HlAdminMatrixTransfer(ctx *gin.Context) {
	// 获取当前用户ID
	userID, exists := ctx.Get("user_id")
	if !exists {
		ucommon.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return
	}

	// 检查用户是否有管理员权限和转账权限
	var role models.Role
	if err := c.db.Joins("JOIN user_roles ON user_roles.role_id = roles.id").
		Where("user_roles.user_id = ? AND roles.status = 1", userID).
		First(&role).Error; err != nil {
		ucommon.Error(ctx, http.StatusForbidden, "NO_PERMISSION", err)
		return
	}

	// 检查是否有管理员权限
	if role.Permissions == nil {
		role.Permissions = make(models.PermissionsMap)
	}
	// 检查是否有矩阵转账权限
	if !role.Permissions["matrix_transfer"] {
		ucommon.Error(ctx, http.StatusForbidden, "NO_MATRIX_TRANSFER_PERMISSION", nil)
		return
	}

	var req struct {
		Currency        string `json:"currency" binding:"required"`
		PlatformAccount string `json:"platformAccount" binding:"required"`
		TransferAmount  string `json:"transferAmount" binding:"required"`
		TransferType    string `json:"transferType" binding:"required,oneof=transfer_in transfer_out"`
		Remark          string `json:"remark"`
	}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ucommon.Error(ctx, http.StatusBadRequest, "invalid_params", fmt.Errorf("参数验证失败: %v", err))
		return
	}

	// 验证转账金额
	amount, err := strconv.ParseFloat(req.TransferAmount, 64)
	if err != nil {
		ucommon.Error(ctx, http.StatusBadRequest, "invalid_amount_format", fmt.Errorf("转账金额格式错误: %v", err))
		return
	}
	if amount <= 0 {
		ucommon.Error(ctx, http.StatusBadRequest, "invalid_amount", fmt.Errorf("转账金额必须大于0"))
		return
	}

	// 开启事务，确保原子性
	tx := c.db.Begin()
	if tx.Error != nil {
		ucommon.Error(ctx, http.StatusInternalServerError, "TRANSACTION_START_FAILED", tx.Error)
		return
	}
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 第一步：验证转账对象
	var matrixAccount models.UserMatrixAccount
	if err := tx.Where("matrix_account = ? AND status = 'active'", req.PlatformAccount).First(&matrixAccount).Error; err != nil {
		tx.Rollback()
		if err == gorm.ErrRecordNotFound {
			ucommon.Error(ctx, http.StatusBadRequest, "MATRIX_ACCOUNT_NOT_FOUND", fmt.Errorf("未找到有效的矩阵账户: %s", req.PlatformAccount))
		} else {
			ucommon.Error(ctx, http.StatusInternalServerError, "DATABASE_ERROR", err)
		}
		return
	}

	// 检查是否为HlPay平台
	if matrixAccount.PlatformType != "hlpay" {
		tx.Rollback()
		ucommon.Error(ctx, http.StatusBadRequest, "NOT_HLPAY_PLATFORM", fmt.Errorf("该账户不是HlPay平台账户"))
		return
	}

	// 获取用户角色，验证转账权限
	var userRole models.UserRole
	if err := tx.Where("user_id = ?", matrixAccount.UserID).First(&userRole).Error; err != nil {
		tx.Rollback()
		if err == gorm.ErrRecordNotFound {
			ucommon.Error(ctx, http.StatusBadRequest, "user_role_not_found",
				fmt.Errorf("用户未分配角色，用户ID: %d", matrixAccount.UserID))
		} else {
			ucommon.Error(ctx, http.StatusInternalServerError, "get_user_roles_failed", err)
		}
		return
	}

	// 只允许 role_id = 2 或 3 的用户转账
	if userRole.RoleID != 2 && userRole.RoleID != 3 {
		tx.Rollback()
		ucommon.Error(ctx, http.StatusForbidden, "NO_TRANSFER_PERMISSION", fmt.Errorf("该用户没有转账权限，角色ID: %d", userRole.RoleID))
		return
	}

	// 第二步：获取可划拨余额并验证
	availableBalance, err := services.GetAvailableBalance(ctx.Request.Context(), c.hlPayClient, tx)
	if err != nil {
		tx.Rollback()
		ucommon.Error(ctx, http.StatusInternalServerError, "GET_AVAILABLE_BALANCE_FAILED", err)
		return
	}

	// 比较划转金额和可划拨总额
	if amount > availableBalance {
		tx.Rollback()
		ucommon.Error(ctx, http.StatusBadRequest, "insufficient_balance",
			fmt.Errorf("可划拨余额不足，当前可划拨: %.2f，请求划拨: %.2f", availableBalance, amount))
		return
	}

	// 如果是转出操作，需要验证 hlpay_account_balances 表中的余额是否足够
	if req.TransferType == "transfer_out" {
		var hlpayBalance models.HlPayAccountBalance
		if err := tx.Where("owner_no = ? AND status = 'active'", req.PlatformAccount).First(&hlpayBalance).Error; err != nil {
			if err == gorm.ErrRecordNotFound {
				tx.Rollback()
				ucommon.Error(ctx, http.StatusBadRequest, "HLPAY_ACCOUNT_BALANCE_NOT_FOUND",
					fmt.Errorf("未找到账户余额记录: %s", req.PlatformAccount))
			} else {
				tx.Rollback()
				ucommon.Error(ctx, http.StatusInternalServerError, "DATABASE_ERROR", err)
			}
			return
		}

		// 检查余额是否足够
		amountDecimal := decimal.NewFromFloat(amount)
		if hlpayBalance.RealTimeBalance.LessThan(amountDecimal) {
			tx.Rollback()
			ucommon.Error(ctx, http.StatusBadRequest, "insufficient_balance",
				fmt.Errorf("账户余额不足，当前余额: %s，请求转出: %.2f", hlpayBalance.RealTimeBalance.String(), amount))
			return
		}
	}

	// 第三步：生成转账记录
	transferRecord := models.AdminTransferRecord{
		AdminID:         userID.(int64),
		Platform:        "hlpay",
		PlatformAccount: req.PlatformAccount,
		TransferAmount:  amount,
		Currency:        req.Currency,
		TransferType:    req.TransferType,
		Status:          "processing",
		Remark:          req.Remark,
	}
	if err := tx.Create(&transferRecord).Error; err != nil {
		tx.Rollback()
		ucommon.Error(ctx, http.StatusInternalServerError, "CREATE_TRANSFER_RECORD_FAILED", err)
		return
	}

	// 第四步：执行划拨操作
	amountDecimal := decimal.NewFromFloat(amount)
	var updateAmount decimal.Decimal
	if req.TransferType == "transfer_in" {
		updateAmount = amountDecimal
	} else {
		updateAmount = amountDecimal.Neg()
	}

	// 根据角色ID执行不同的余额更新逻辑
	if userRole.RoleID == 2 {
		// RoleID = 2（普通用户）：只更新 hlpay_account_balances 表
		if err := tx.Model(&models.HlPayAccountBalance{}).
			Where("owner_no = ? AND status = 'active'", req.PlatformAccount).
			Update("real_time_balance", gorm.Expr("real_time_balance + ?", updateAmount)).Error; err != nil {
			tx.Rollback()
			ucommon.Error(ctx, http.StatusInternalServerError, "UPDATE_HLPAY_BALANCE_FAILED", err)
			return
		}
	} else if userRole.RoleID == 3 {
		// RoleID = 3（代理商）：更新 hlpay_account_balances 表和 master_accounts 表
		if err := tx.Model(&models.HlPayAccountBalance{}).
			Where("owner_no = ? AND status = 'active'", req.PlatformAccount).
			Update("real_time_balance", gorm.Expr("real_time_balance + ?", updateAmount)).Error; err != nil {
			tx.Rollback()
			ucommon.Error(ctx, http.StatusInternalServerError, "UPDATE_HLPAY_BALANCE_FAILED", err)
			return
		}

		// 同时更新 master_accounts 表
		if err := tx.Model(&models.MasterAccount{}).
			Where("user_id = ?", matrixAccount.UserID).
			Update("balance", gorm.Expr("balance + ?", updateAmount)).Error; err != nil {
			tx.Rollback()
			ucommon.Error(ctx, http.StatusInternalServerError, "UPDATE_MASTER_ACCOUNT_BALANCE_FAILED", err)
			return
		}
	}

	// 第五步：更新总划拨金额
	if err := tx.Model(&models.UserMatrixAccount{}).
		Where("matrix_account = ? AND status = 'active'", req.PlatformAccount).
		Update("total_transfer_amount", gorm.Expr("total_transfer_amount + ?", updateAmount)).Error; err != nil {
		tx.Rollback()
		ucommon.Error(ctx, http.StatusInternalServerError, "UPDATE_TRANSFER_AMOUNT_FAILED", err)
		return
	}

	// 生成交易ID
	transactionID := fmt.Sprintf("HL%s%d", req.PlatformAccount, time.Now().UnixNano())

	// 第六步：更新转账记录为成功状态
	if err := tx.Model(&models.AdminTransferRecord{}).Where("id = ?", transferRecord.ID).
		Updates(map[string]interface{}{
			"Status":        "success",
			"TransactionID": transactionID,
			"ErrorMessage":  "",
		}).Error; err != nil {
		tx.Rollback()
		ucommon.Error(ctx, http.StatusInternalServerError, "UPDATE_TRANSFER_RECORD_FAILED", err)
		return
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		ucommon.Error(ctx, http.StatusInternalServerError, "TRANSACTION_COMMIT_FAILED", err)
		return
	}

	// 生成带Matrix_account的短交易流水号（不超过32位）
	accountSuffix := req.PlatformAccount
	if len(accountSuffix) > 8 {
		accountSuffix = accountSuffix[len(accountSuffix)-8:]
	}
	timestamp := time.Now().UnixNano() / 1e6 // 毫秒
	randomNum := rand.Intn(10000)            // 4位随机数
	shortTransactionID := fmt.Sprintf("%s%x%04d", accountSuffix, timestamp, randomNum)
	if len(shortTransactionID) > 32 {
		shortTransactionID = shortTransactionID[:32]
	}

	// 创建通知
	notificationService := service.NewNotificationService()

	// 根据转账类型设置标题和操作类型
	var title, operationType string
	switch req.TransferType {
	case "transfer_in":
		title = "资金转入通知"
		operationType = "转入"
	case "transfer_out":
		title = "资金转出通知"
		operationType = "转出"
	case "refund":
		title = "资金退还通知"
		operationType = "退还"
	default:
		title = "资金变动通知"
		operationType = "变动"
	}

	notification := &models.Notification{
		UserID: matrixAccount.UserID,
		TypeID: 3, // 使用type_id 3
		Title:  title,
		Content: fmt.Sprintf("您的账户(%s)%s%.2f%s，交易流水号：%s",
			req.PlatformAccount,
			operationType,
			amount,
			req.Currency,
			shortTransactionID,
		),
		Data:   models.JSON(fmt.Sprintf(`{"Matrix_account":"%s","transaction_ID":"%s","platform":"hlpay"}`, req.PlatformAccount, shortTransactionID)),
		Status: "UNREAD",
	}
	if err := notificationService.CreateNotification(ctx, notification); err != nil {
		fmt.Printf("创建通知失败: %v\n", err)
	}

	// 返回成功响应
	response := map[string]interface{}{
		"transactionId": transactionID,
		"matrixAccount": req.PlatformAccount,
		"amount":        amount,
		"currency":      req.Currency,
		"transferType":  req.TransferType,
		"status":        "success",
	}

	ucommon.Success(ctx, response)
}

// GetHlPayAccountBalance 获取HlPay账户余额（调用GetAccountInfo接口）
func (c *HlAdminController) GetHlPayAccountBalance(ctx *gin.Context) {
	result, err := services.GetAccountInfo(ctx.Request.Context(), c.hlPayClient, c.db)
	if err != nil {
		fmt.Printf("[HlAdmin] 获取账户信息失败: %v\n", err)
		ucommon.Error(ctx, http.StatusServiceUnavailable, "HLPAY_SERVICE_UNAVAILABLE",
			fmt.Errorf("HlPay服务暂时不可用，请稍后重试: %v", err))
		return
	}

	// 只返回 result.Data，去掉多余嵌套
	ucommon.Success(ctx, result.Data)
}

// GetUserTransactions 管理员查询用户交易记录
func (c *HlAdminController) GetUserTransactions(ctx *gin.Context) {

	// 解析查询参数
	var req struct {
		UserID        int64  `form:"user_id"`
		MatrixAccount string `form:"matrix_account"`
		PageIndex     int    `form:"pageIndex,default=1"`
		PageSize      int    `form:"pageSize,default=10"`
	}

	if err := ctx.ShouldBindQuery(&req); err != nil {
		ucommon.Error(ctx, http.StatusBadRequest, "invalid_params", fmt.Errorf("参数验证失败: %v", err))
		return
	}

	// 验证分页参数
	if req.PageIndex < 1 {
		req.PageIndex = 1
	}
	if req.PageSize < 1 {
		req.PageSize = 10
	}

	// 必须提供用户ID或MatrixAccount之一
	if req.UserID == 0 && req.MatrixAccount == "" {
		ucommon.Error(ctx, http.StatusBadRequest, "missing_user_identifier", fmt.Errorf("必须提供用户ID或MatrixAccount"))
		return
	}

	// 确定要查询的用户ID
	var targetUserID int64
	if req.UserID != 0 {
		// 直接使用提供的用户ID
		targetUserID = req.UserID
	} else {
		// 通过MatrixAccount查找用户ID
		var userMatrixAccount models.UserMatrixAccount
		if err := c.db.Where("matrix_account = ? AND status = 'active'", req.MatrixAccount).First(&userMatrixAccount).Error; err != nil {
			if err == gorm.ErrRecordNotFound {
				ucommon.Error(ctx, http.StatusNotFound, "matrix_account_not_found", fmt.Errorf("未找到MatrixAccount: %s", req.MatrixAccount))
			} else {
				ucommon.Error(ctx, http.StatusInternalServerError, "database_error", err)
			}
			return
		}
		targetUserID = userMatrixAccount.UserID
	}

	// 验证目标用户是否存在
	var targetUser models.User
	if err := c.db.Where("id = ?", targetUserID).First(&targetUser).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			ucommon.Error(ctx, http.StatusNotFound, "user_not_found", fmt.Errorf("未找到用户ID: %d", targetUserID))
		} else {
			ucommon.Error(ctx, http.StatusInternalServerError, "database_error", err)
		}
		return
	}

	// 创建交易缓存服务实例
	cacheService := service.NewHlPayTransactionCacheService(c.hlPayClient, nil)
	cacheController := NewHlPayTransactionCacheController(cacheService)

	// 设置用户ID到上下文中，模拟用户登录状态
	ctx.Set("user_id", targetUserID)

	// 调用交易缓存控制器的GetUserTransactions方法
	cacheController.GetUserTransactions(ctx)
}

// GetUserTransactionsByMatrixAccount 通过MatrixAccount查询用户交易记录（便捷方法）
func (c *HlAdminController) GetUserTransactionsByMatrixAccount(ctx *gin.Context) {
	// 获取当前管理员用户ID
	adminID, exists := ctx.Get("user_id")
	if !exists {
		ucommon.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return
	}

	// 检查管理员权限
	var adminRole models.Role
	if err := c.db.Joins("JOIN user_roles ON user_roles.role_id = roles.id").
		Where("user_roles.user_id = ? AND roles.status = 1", adminID).
		First(&adminRole).Error; err != nil {
		ucommon.Error(ctx, http.StatusForbidden, "NO_PERMISSION", err)
		return
	}

	// 检查是否有查看用户交易记录的权限
	if adminRole.Permissions == nil {
		adminRole.Permissions = make(models.PermissionsMap)
	}
	if !adminRole.Permissions["view_user_transactions"] {
		ucommon.Error(ctx, http.StatusForbidden, "NO_VIEW_TRANSACTIONS_PERMISSION", nil)
		return
	}

	// 从路径参数获取MatrixAccount
	matrixAccount := ctx.Param("matrix_account")
	if matrixAccount == "" {
		ucommon.Error(ctx, http.StatusBadRequest, "matrix_account_required", fmt.Errorf("MatrixAccount不能为空"))
		return
	}

	// 通过MatrixAccount查找用户ID
	var userMatrixAccount models.UserMatrixAccount
	if err := c.db.Where("matrix_account = ? AND status = 'active'", matrixAccount).First(&userMatrixAccount).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			ucommon.Error(ctx, http.StatusNotFound, "matrix_account_not_found", fmt.Errorf("未找到MatrixAccount: %s", matrixAccount))
		} else {
			ucommon.Error(ctx, http.StatusInternalServerError, "database_error", err)
		}
		return
	}

	// 验证目标用户是否存在
	var targetUser models.User
	if err := c.db.Where("id = ?", userMatrixAccount.UserID).First(&targetUser).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			ucommon.Error(ctx, http.StatusNotFound, "user_not_found", fmt.Errorf("未找到用户ID: %d", userMatrixAccount.UserID))
		} else {
			ucommon.Error(ctx, http.StatusInternalServerError, "database_error", err)
		}
		return
	}

	// 创建交易缓存服务实例
	cacheService := service.NewHlPayTransactionCacheService(c.hlPayClient, nil)
	cacheController := NewHlPayTransactionCacheController(cacheService)

	// 设置用户ID到上下文中，模拟用户登录状态
	ctx.Set("user_id", userMatrixAccount.UserID)

	// 调用交易缓存控制器的GetUserTransactions方法
	cacheController.GetUserTransactions(ctx)
}
